home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / FLEX-TC_ / MISC.C < prev    next >
Text File  |  1990-01-03  |  13KB  |  714 lines

  1. /* misc - miscellaneous flex routines */
  2.  
  3. /*
  4.  * Copyright (c) 1989 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant to
  11.  * contract no. DE-AC03-76SF00098 between the United States Department of
  12.  * Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted
  15.  * provided that the above copyright notice and this paragraph are
  16.  * duplicated in all such forms and that any documentation,
  17.  * advertising materials, and other materials related to such
  18.  * distribution and use acknowledge that the software was developed
  19.  * by the University of California, Berkeley.  The name of the
  20.  * University may not be used to endorse or promote products derived
  21.  * from this software without specific prior written permission.
  22.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  23.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  24.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25.  */
  26.  
  27. #ifndef lint
  28.  
  29. static char copyright[] =
  30.     "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  31. static char CR_continuation[] = "@(#) All rights reserved.\n";
  32.  
  33. static char rcsid[] =
  34.     "@(#) $Header: misc.c,v 2.0 89/06/20 15:50:00 vern Locked $ (LBL)";
  35.  
  36. #endif
  37.  
  38. #include <ctype.h>
  39. #include "flexdef.h"
  40.  
  41. #ifdef THINK_C
  42. #include <stdlib.h>
  43. #else
  44. char *malloc(), *realloc();
  45. #endif
  46.  
  47.  
  48. /* action_out - write the actions from the temporary file to lex.yy.c
  49.  *
  50.  * synopsis
  51.  *     action_out();
  52.  *
  53.  *     Copies the action file up to %% (or end-of-file) to lex.yy.c
  54.  */
  55.  
  56. action_out()
  57.  
  58.     {
  59.     char buf[MAXLINE];
  60.  
  61.     while ( fgets( buf, MAXLINE, temp_action_file ) != NULL )
  62.     if ( buf[0] == '%' && buf[1] == '%' )
  63.         break;
  64.     else
  65.         fputs( buf, stdout );
  66.     }
  67.  
  68.  
  69. /* allocate_array - allocate memory for an integer array of the given size */
  70.  
  71. char *allocate_array( size, element_size )
  72. int size, element_size;
  73.  
  74.     {
  75.     register char *mem;
  76.  
  77.     /* on 16-bit int machines (e.g., 80286) we might be trying to
  78.      * allocate more than a signed int can hold, and that won't
  79.      * work.  Cheap test:
  80.      */
  81.     if ( element_size * size <= 0 )
  82.         flexfatal( "request for < 1 byte in allocate_array()" );
  83.     
  84.     mem = malloc( (unsigned) (element_size * size) );
  85.  
  86.     if ( mem == NULL )
  87.     flexfatal( "memory allocation failed in allocate_array()" );
  88.  
  89.     return ( mem );
  90.     }
  91.  
  92.  
  93. /* all_lower - true if a string is all lower-case
  94.  *
  95.  * synopsis:
  96.  *    char *str;
  97.  *    int all_lower();
  98.  *    true/false = all_lower( str );
  99.  */
  100.  
  101. int all_lower( str )
  102. register char *str;
  103.  
  104.     {
  105.     while ( *str )
  106.     {
  107.     if ( ! islower( *str ) )
  108.         return ( 0 );
  109.     ++str;
  110.     }
  111.  
  112.     return ( 1 );
  113.     }
  114.  
  115.  
  116. /* all_upper - true if a string is all upper-case
  117.  *
  118.  * synopsis:
  119.  *    char *str;
  120.  *    int all_upper();
  121.  *    true/false = all_upper( str );
  122.  */
  123.  
  124. int all_upper( str )
  125. register char *str;
  126.  
  127.     {
  128.     while ( *str )
  129.     {
  130.     if ( ! isupper( *str ) )
  131.         return ( 0 );
  132.     ++str;
  133.     }
  134.  
  135.     return ( 1 );
  136.     }
  137.  
  138.  
  139. /* bubble - bubble sort an integer array in increasing order
  140.  *
  141.  * synopsis
  142.  *   int v[n], n;
  143.  *   bubble( v, n );
  144.  *
  145.  * description
  146.  *   sorts the first n elements of array v and replaces them in
  147.  *   increasing order.
  148.  *
  149.  * passed
  150.  *   v - the array to be sorted
  151.  *   n - the number of elements of 'v' to be sorted */
  152.  
  153. bubble( v, n )
  154. int v[], n;
  155.  
  156.     {
  157.     register int i, j, k;
  158.  
  159.     for ( i = n; i > 1; --i )
  160.     for ( j = 1; j < i; ++j )
  161.         if ( v[j] > v[j + 1] )    /* compare */
  162.         {
  163.         k = v[j];    /* exchange */
  164.         v[j] = v[j + 1];
  165.         v[j + 1] = k;
  166.         }
  167.     }
  168.  
  169.  
  170. /* clower - replace upper-case letter to lower-case
  171.  *
  172.  * synopsis:
  173.  *    char clower(), c;
  174.  *    c = clower( c );
  175.  */
  176.  
  177. char clower( c )
  178. register char c;
  179.  
  180.     {
  181.     return ( isupper(c) ? tolower(c) : c );
  182.     }
  183.  
  184.  
  185. /* copy_string - returns a dynamically allocated copy of a string
  186.  *
  187.  * synopsis
  188.  *    char *str, *copy, *copy_string();
  189.  *    copy = copy_string( str );
  190.  */
  191.  
  192. char *copy_string( str )
  193. register char *str;
  194.  
  195.     {
  196.     register char *c;
  197.     char *copy;
  198.  
  199.     /* find length */
  200.     for ( c = str; *c; ++c )
  201.     ;
  202.  
  203.     copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
  204.  
  205.     if ( copy == NULL )
  206.     flexfatal( "dynamic memory failure in copy_string()" );
  207.  
  208.     for ( c = copy; (*c++ = *str++); )
  209.     ;
  210.     
  211.     return ( copy );
  212.     }
  213.  
  214.  
  215. /* cshell - shell sort a character array in increasing order
  216.  *
  217.  * synopsis
  218.  *
  219.  *   char v[n];
  220.  *   int n;
  221.  *   cshell( v, n );
  222.  *
  223.  * description
  224.  *   does a shell sort of the first n elements of array v.
  225.  *
  226.  * passed
  227.  *   v - array to be sorted
  228.  *   n - number of elements of v to be sorted
  229.  */
  230. cshell( v, n )
  231. char v[];
  232. int n;
  233.  
  234.     {
  235.     int gap, i, j, jg;
  236.     char k;
  237.  
  238.     for ( gap = n / 2; gap > 0; gap = gap / 2 )
  239.     for ( i = gap; i < n; ++i )
  240.         for ( j = i - gap; j >= 0; j = j - gap )
  241.         {
  242.         jg = j + gap;
  243.  
  244.         if ( v[j] <= v[jg] )
  245.             break;
  246.  
  247.         k = v[j];
  248.         v[j] = v[jg];
  249.         v[jg] = k;
  250.         }
  251.     }
  252.  
  253.  
  254. /* dataend - finish up a block of data declarations
  255.  *
  256.  * synopsis
  257.  *    dataend();
  258.  */
  259. dataend()
  260.  
  261.     {
  262.     if ( datapos > 0 )
  263.     dataflush();
  264.  
  265.     /* add terminator for initialization */
  266.     puts( "    } ;\n" );
  267.  
  268.     dataline = 0;
  269.     }
  270.  
  271.  
  272.  
  273. /* dataflush - flush generated data statements
  274.  *
  275.  * synopsis
  276.  *    dataflush();
  277.  */
  278. dataflush()
  279.  
  280.     {
  281.     putchar( '\n' );
  282.  
  283.     if ( ++dataline >= NUMDATALINES )
  284.     {
  285.     /* put out a blank line so that the table is grouped into
  286.      * large blocks that enable the user to find elements easily
  287.      */
  288.     putchar( '\n' );
  289.     dataline = 0;
  290.     }
  291.  
  292.     /* reset the number of characters written on the current line */
  293.     datapos = 0;
  294.     }
  295.  
  296. /* flex_gettime - return current time
  297.  *
  298.  * synopsis
  299.  *    char *flex_gettime(), *time_str;
  300.  *    time_str = flex_gettime();
  301.  *
  302.  * note
  303.  *    the routine name has the "flex_" prefix because of name clashes
  304.  *    with Turbo-C
  305.  */
  306.  
  307. /* include sys/types.h to use time_t and make lint happy */
  308.  
  309. #ifdef THINK_C
  310. #include <ctype.h>
  311. #include <time.h>
  312. #else
  313. #ifndef MS_DOS
  314. #ifndef VMS
  315. #include <sys/types.h>
  316. #else
  317. #include <types.h>
  318. #endif
  319. #endif
  320. #endif
  321.  
  322. #ifdef MS_DOS
  323. #include <time.h>
  324. typedef long time_t;
  325. #endif
  326.  
  327. char *flex_gettime()
  328.  
  329.     {
  330.     time_t t, time();
  331.     char *result, *ctime(), *copy_string();
  332.  
  333. #ifdef THINK_C
  334.     t = time( (time_t *) 0 );
  335. #else
  336.     t = time( (long *) 0 );
  337. #endif
  338.  
  339.     result = copy_string( ctime( &t ) );
  340.  
  341.     /* get rid of trailing newline */
  342.     result[24] = '\0';
  343.  
  344.     return ( result );
  345.     }
  346.  
  347.  
  348. /* lerrif - report an error message formatted with one integer argument
  349.  *
  350.  * synopsis
  351.  *    char msg[];
  352.  *    int arg;
  353.  *    lerrif( msg, arg );
  354.  */
  355.  
  356. lerrif( msg, arg )
  357. char msg[];
  358. int arg;
  359.  
  360.     {
  361.     char errmsg[MAXLINE];
  362.     (void) sprintf( errmsg, msg, arg );
  363.     flexerror( errmsg );
  364.     }
  365.  
  366.  
  367. /* lerrsf - report an error message formatted with one string argument
  368.  *
  369.  * synopsis
  370.  *    char msg[], arg[];
  371.  *    lerrsf( msg, arg );
  372.  */
  373.  
  374. lerrsf( msg, arg )
  375. char msg[], arg[];
  376.  
  377.     {
  378.     char errmsg[MAXLINE];
  379.  
  380.     (void) sprintf( errmsg, msg, arg );
  381.     flexerror( errmsg );
  382.     }
  383.  
  384.  
  385. /* flexerror - report an error message and terminate
  386.  *
  387.  * synopsis
  388.  *    char msg[];
  389.  *    flexerror( msg );
  390.  */
  391.  
  392. flexerror( msg )
  393. char msg[];
  394.  
  395.     {
  396.     fprintf( stderr, "flex: %s\n", msg );
  397.  
  398.     flexend( 1 );
  399.     }
  400.  
  401.  
  402. /* flexfatal - report a fatal error message and terminate
  403.  *
  404.  * synopsis
  405.  *    char msg[];
  406.  *    flexfatal( msg );
  407.  */
  408.  
  409. flexfatal( msg )
  410. char msg[];
  411.  
  412.     {
  413.     fprintf( stderr, "flex: fatal internal error %s\n", msg );
  414.     flexend( 1 );
  415.     }
  416.  
  417.  
  418. /* line_directive_out - spit out a "# line" statement */
  419.  
  420. line_directive_out( output_file_name )
  421. FILE *output_file_name;
  422.  
  423.     {
  424.     if ( infilename && gen_line_dirs ) 
  425.         fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
  426.     }
  427.  
  428.  
  429. /* mk2data - generate a data statement for a two-dimensional array
  430.  *
  431.  * synopsis
  432.  *    int value;
  433.  *    mk2data( value );
  434.  *
  435.  *  generates a data statement initializing the current 2-D array to "value"
  436.  */
  437. mk2data( value )
  438. int value;
  439.  
  440.     {
  441.     if ( datapos >= NUMDATAITEMS )
  442.     {
  443.     putchar( ',' );
  444.     dataflush();
  445.     }
  446.  
  447.     if ( datapos == 0 )
  448.     /* indent */
  449.     fputs( "    ", stdout );
  450.  
  451.     else
  452.     putchar( ',' );
  453.  
  454.     ++datapos;
  455.  
  456.     printf( "%5d", value );
  457.     }
  458.  
  459.  
  460. /* mkdata - generate a data statement
  461.  *
  462.  * synopsis
  463.  *    int value;
  464.  *    mkdata( value );
  465.  *
  466.  *  generates a data statement initializing the current array element to
  467.  *  "value"
  468.  */
  469. mkdata( value )
  470. int value;
  471.  
  472.     {
  473.     if ( datapos >= NUMDATAITEMS )
  474.     {
  475.     putchar( ',' );
  476.     dataflush();
  477.     }
  478.  
  479.     if ( datapos == 0 )
  480.     /* indent */
  481.     fputs( "    ", stdout );
  482.  
  483.     else
  484.     putchar( ',' );
  485.  
  486.     ++datapos;
  487.  
  488.     printf( "%5d", value );
  489.     }
  490.  
  491.  
  492. /* myctoi - return the integer represented by a string of digits
  493.  *
  494.  * synopsis
  495.  *    char array[];
  496.  *    int val, myctoi();
  497.  *    val = myctoi( array );
  498.  *
  499.  */
  500.  
  501. int myctoi( array )
  502. char array[];
  503.  
  504.     {
  505.     int val = 0;
  506.  
  507.     (void) sscanf( array, "%d", &val );
  508.  
  509.     return ( val );
  510.     }
  511.  
  512.  
  513. /* myesc - return character corresponding to escape sequence
  514.  *
  515.  * synopsis
  516.  *    char array[], c, myesc();
  517.  *    c = myesc( array );
  518.  *
  519.  */
  520.  
  521. char myesc( array )
  522. char array[];
  523.  
  524.     {
  525.     switch ( array[1] )
  526.     {
  527.     case 'a': return ( '\a' );
  528.     case 'b': return ( '\b' );
  529.     case 'f': return ( '\f' );
  530.     case 'n': return ( '\n' );
  531.     case 'r': return ( '\r' );
  532.     case 't': return ( '\t' );
  533.     case 'v': return ( '\v' );
  534.  
  535.     case '0':
  536.     case '1':
  537.     case '2':
  538.     case '3':
  539.     case '4':
  540.     case '5':
  541.     case '6':
  542.     case '7':
  543.     case '8':
  544.     case '9':
  545.         { /* \<octal> */
  546.         char c, esc_char;
  547.         register int sptr = 1;
  548.  
  549.         while ( isdigit(array[sptr]) )
  550.         /* don't increment inside loop control because if
  551.          * isdigit() is a macro it will expand it to two
  552.          * increments ...
  553.          */
  554.         ++sptr;
  555.  
  556.         c = array[sptr];
  557.         array[sptr] = '\0';
  558.  
  559.         esc_char = otoi( array + 1 );
  560.         array[sptr] = c;
  561.  
  562.         if ( esc_char == '\0' )
  563.         {
  564.         synerr( "escape sequence for null not allowed" );
  565.         return ( 1 );
  566.         }
  567.  
  568.         return ( esc_char );
  569.         }
  570.  
  571.     default:
  572.         return ( array[1] );
  573.     }
  574.     }
  575.  
  576.  
  577. /* otoi - convert an octal digit string to an integer value
  578.  *
  579.  * synopsis:
  580.  *    int val, otoi();
  581.  *    char str[];
  582.  *    val = otoi( str );
  583.  */
  584.  
  585. int otoi( str )
  586. char str[];
  587.  
  588.     {
  589.     int result;
  590.  
  591.     (void) sscanf( str, "%o", &result );
  592.  
  593.     return ( result );
  594.     }
  595.  
  596.  
  597. /* readable_form - return the the human-readable form of a character
  598.  *
  599.  * synopsis:
  600.  *    int c;
  601.  *    char *readable_form();
  602.  *    <string> = readable_form( c );
  603.  *
  604.  * The returned string is in static storage.
  605.  */
  606.  
  607. char *readable_form( c )
  608. register int c;
  609.  
  610.     {
  611.     static char rform[10];
  612.  
  613.     if ( (c >= 0 && c < 32) || c == 127 )
  614.     {
  615.     switch ( c )
  616.         {
  617.         case '\n': return ( "\\n" );
  618.         case '\t': return ( "\\t" );
  619.         case '\f': return ( "\\f" );
  620.         case '\r': return ( "\\r" );
  621.         case '\b': return ( "\\b" );
  622.  
  623.         default:
  624.         sprintf( rform, "\\%.3o", c );
  625.         return ( rform );
  626.         }
  627.     }
  628.     
  629.     else if ( c == ' ' )
  630.     return ( "' '" );
  631.     
  632.     else
  633.     {
  634.     rform[0] = c;
  635.     rform[1] = '\0';
  636.  
  637.     return ( rform );
  638.     }
  639.     }
  640.  
  641.  
  642. /* reallocate_array - increase the size of a dynamic array */
  643.  
  644. char *reallocate_array( array, size, element_size )
  645. char *array;
  646. int size, element_size;
  647.  
  648.     {
  649.     register char *new_array;
  650.  
  651.     /* same worry as in allocate_array(): */
  652.     if ( size * element_size <= 0 )
  653.         flexfatal( "attempt to increase array size by less than 1 byte" );
  654.     
  655.     new_array = realloc( array, (unsigned) (size * element_size ));
  656.  
  657.     if ( new_array == NULL )
  658.     flexfatal( "attempt to increase array size failed" );
  659.     
  660.     return ( new_array );
  661.     }
  662.  
  663.  
  664. /* skelout - write out one section of the skeleton file
  665.  *
  666.  * synopsis
  667.  *    skelout();
  668.  *
  669.  * DESCRIPTION
  670.  *    Copies from skelfile to stdout until a line beginning with "%%" or
  671.  *    EOF is found.
  672.  */
  673. skelout()
  674.  
  675.     {
  676.     char buf[MAXLINE];
  677.  
  678.     while ( fgets( buf, MAXLINE, skelfile ) != NULL )
  679.     if ( buf[0] == '%' && buf[1] == '%' )
  680.         break;
  681.     else
  682.         fputs( buf, stdout );
  683.     }
  684.  
  685.  
  686. /* transition_struct_out - output a yy_trans_info structure
  687.  *
  688.  * synopsis
  689.  *     int element_v, element_n;
  690.  *     transition_struct_out( element_v, element_n );
  691.  *
  692.  * outputs the yy_trans_info structure with the two elements, element_v and
  693.  * element_n.  Formats the output with spaces and carriage returns.
  694.  */
  695.  
  696. transition_struct_out( element_v, element_n )
  697. int element_v, element_n;
  698.  
  699.     {
  700.     printf( "%7d, %5d,", element_v, element_n );
  701.  
  702.     datapos += TRANS_STRUCT_PRINT_LENGTH;
  703.  
  704.     if ( datapos >= 75 )
  705.     {
  706.     putchar( '\n' );
  707.  
  708.     if ( ++dataline % 10 == 0 )
  709.         putchar( '\n' );
  710.  
  711.     datapos = 0;
  712.     }
  713.     }
  714.